package cn.teawooo.tree.string;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * 功能描述：
 * @author zhaozhijie
 * @time : 2013-5-3 下午4:58:58
 */
public class StringParser {
    private final static char L = '[';//
    private final static char R = ']';//
    private final static char S = ',';//
    private final static char P = '.';//

    private String pattern;

    public StringParser(String p) {
        this.pattern = p.replaceAll("[^0-9a-zA-Z,.\\]\\[\\{]", "");
    }

    private void pushStack(StringBuffer sb, Stack<String> stack) {
        if (sb.length() > 0) {
            stack.push(sb.toString());
        }
        clearStringBuffer(sb);
    }

    private String popStack(StringBuffer sb, Stack<String> stack) {
        for (int i = 0; i < stack.size() - 1; i++) {
            sb.append(stack.get(i)).append(P);
        }
        sb.append(stack.pop());
        String result = sb.toString();
        clearStringBuffer(sb);
        return result;
    }

    private void clearStringBuffer(StringBuffer sb) {
        sb.delete(0, sb.length());
    }

    public StringTree parseTree() {
        StringBuffer sb = new StringBuffer();

        StringTree st = new StringTree();
        StringNode root = null;
        StringNode currNode = null;

        char[] cs = pattern.toCharArray();
        for (char c : cs) {
            switch (c) {
            case L:
                if (root == null) {
                    root = new StringNode(sb.toString());
                    currNode = root;
                } else {
                    currNode = currNode.grownAndReturnChild(new StringNode(sb.toString()));
                }
                clearStringBuffer(sb);
                break;
            case R:
                if (sb.length() > 0) {
                    currNode.grown(new StringNode(sb.toString()));
                }
                currNode = currNode.getParent();
                clearStringBuffer(sb);
                break;
            case S:
                if (sb.length() > 0) {
                    currNode.grown(new StringNode(sb.toString()));
                }
                clearStringBuffer(sb);
                break;
            case P:
                if (root == null) {
                    sb.append(c);
                } else {
                    currNode = currNode.grown(new StringNode(sb.toString()));
                    clearStringBuffer(sb);
                }
                break;
            default:
                sb.append(c);
            }
        }

        if (sb.length() > 0) {
            if (root == null) {
                root = new StringNode(sb.toString());
            } else {
                currNode.grown(new StringNode(sb.toString()));
            }
        }

        st.setRoot(root);

        return st;
    }

    public List<String> parse() {
        StringBuffer sb = new StringBuffer();
        Stack<String> stack = new Stack<String>();
        List<String> result = new ArrayList<String>();

        char[] cs = pattern.toCharArray();
        for (char c : cs) {
            switch (c) {
            case L:
                pushStack(sb, stack);
                break;
            case R:
                pushStack(sb, stack);
                result.add(popStack(sb, stack));
                break;
            case S:
                pushStack(sb, stack);
                result.add(popStack(sb, stack));
                break;
            case P:
                pushStack(sb, stack);
                break;
            default:
                sb.append(c);
            }
        }
        result.add(popStack(sb, stack));

        return result;
    }
}
